package be.jabapage.snooker.service.competition.impl;

import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;

import org.apache.commons.lang.Validate;

import be.jabapage.snooker.exception.EntityNotFoundException;
import be.jabapage.snooker.exception.MultipleInstanceFoundException;
import be.jabapage.snooker.jdo.competition.TeamCompetitionParticipation;
import be.jabapage.snooker.service.competition.api.ITeamCompetitionParticipationService;

public class AppEngineTeamCompetitionParticipationService implements ITeamCompetitionParticipationService, Serializable {

	private static final long serialVersionUID = -5236663353643345598L;
	private final PersistenceManagerFactory pmf;

	public AppEngineTeamCompetitionParticipationService(final PersistenceManagerFactory pmf) {
		Validate.notNull(pmf,"The persistence Manager factory cannot be null");
		this.pmf = pmf;
	}

	/**
	 * {@inheritDoc}
	 */
	public void store(final TeamCompetitionParticipation teamCompetitionParticipation) {
		Validate.notNull(teamCompetitionParticipation);
		PersistenceManager pm = pmf.getPersistenceManager();
		try {
			pm.makePersistent(teamCompetitionParticipation);
		} finally {
			pm.close();
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public TeamCompetitionParticipation retrieve(final Long key) throws EntityNotFoundException {
		Validate.notNull(key, "A key should be provided.");
		PersistenceManager pm = pmf.getPersistenceManager();
		try {
			TeamCompetitionParticipation objectById = pm.getObjectById(TeamCompetitionParticipation.class, key);
			if (objectById == null) {
				throw new EntityNotFoundException();
			}
			return objectById;
		} finally {
			pm.close();
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public void delete(final Long key) throws EntityNotFoundException {
		Validate.notNull(key, "We cannot delete an instance withour a key.");
		PersistenceManager pm = pmf.getPersistenceManager();
		try {
			TeamCompetitionParticipation dataInstance = pm.getObjectById(TeamCompetitionParticipation.class, key);
			if (dataInstance == null) {
				throw new EntityNotFoundException();
			}

			pm.deletePersistent(dataInstance);
		} finally {
			pm.close();
		}
	}

	public Set<TeamCompetitionParticipation> retrieveAllForSubCompetition(final Long subCompetitionId) {
		Validate.notNull(subCompetitionId, "We need to have subcompetitionId.");
		PersistenceManager pm = pmf.getPersistenceManager();
		Query query = pm.newQuery(TeamCompetitionParticipation.class);
		query.setFilter("subCompetitionId == subCompetitionParam");
		query.declareParameters("Long subCompetitionParam");
		Set<TeamCompetitionParticipation> resultSet = new HashSet<TeamCompetitionParticipation>();

		try {
			@SuppressWarnings("unchecked")
			List<TeamCompetitionParticipation> results = (List<TeamCompetitionParticipation>) query.execute(subCompetitionId);
			if (results != null) {
				resultSet.addAll(results);
			}
		} finally {
			query.closeAll();
			pm.close();
		}
		return resultSet;
	}

	public Set<TeamCompetitionParticipation> retrieveAllForTeam(final Long teamId) {
		Validate.notNull(teamId, "We need to have teamId.");
		PersistenceManager pm = pmf.getPersistenceManager();
		Query query = pm.newQuery(TeamCompetitionParticipation.class);
		query.setFilter("teamId == teamParam");
		query.declareParameters("Long teamParam");
		Set<TeamCompetitionParticipation> resultSet = new HashSet<TeamCompetitionParticipation>();

		try {
			@SuppressWarnings("unchecked")
			List<TeamCompetitionParticipation> results = (List<TeamCompetitionParticipation>) query.execute(teamId);
			if (results != null) {
				resultSet.addAll(results);
			}
		} finally {
			query.closeAll();
			pm.close();
		}
		return resultSet;
	}

	public TeamCompetitionParticipation search(final Long teamId, final String season) throws EntityNotFoundException, MultipleInstanceFoundException {
		Validate.notNull(teamId, "We need to have teamId.");
		Validate.notNull(season, "We need to have season.");
		PersistenceManager pm = pmf.getPersistenceManager();
		Query query = pm.newQuery(TeamCompetitionParticipation.class);
		query.setFilter("teamId == teamParam and season == seasonParam");
		query.declareParameters("Long teamParam, String seasonParam");

		try {
			@SuppressWarnings("unchecked")
			List<TeamCompetitionParticipation> results = (List<TeamCompetitionParticipation>) query.execute(teamId, season);
			if (results.isEmpty()) {
				throw new EntityNotFoundException();
			}
			if (results.size() > 1) {
				throw new MultipleInstanceFoundException();
			}
			return results.get(0);
		} finally {
			query.closeAll();
			pm.close();
		}

	}
}
